package both.map.mapModel;

/**
 * CellContent for visibility information. 
 * 
 * @author jdl
 */
public class VisibilityCell extends ModelCell {

	// has the cell been seen at any point?
	private boolean seen;
	// is the cell currently visible?
	private boolean currentlyVisible;
	
	/**
	 * construct a new VisibilityCell
	 * 
	 * (defaults to unseen and invisible)
	 */
	public VisibilityCell()
	{
		this(false, false, false);
	}
	
	/**
	 * constructs a new VisibilityCell, specifying whether it is part of an
	 * update object or not.
	 */
	private VisibilityCell(boolean forUpdate, boolean seen, boolean currentlyVisible)
	{
		super(forUpdate);
		this.seen = seen;
		this.currentlyVisible = currentlyVisible;
	}
	
	/**
	 * @return true if the cell has been seen already
	 */
	public boolean hasBeenSeen()
	{
		return seen;
	}
	
	/**
	 * @return true if the cell is currently visible
	 */
	public boolean isCurrentlyVisible()
	{
		return currentlyVisible;
	}
	
	/**
	 * set the current visibility of this cell
	 * @param seen true if the cell has been seen
	 * @param visible true if the cell should be currently visible
	 * @return true if change was successfully made
	 */
	public boolean setVisibility(boolean seen, boolean visible)
	{
		if (!isPartOfUpdate()) {
			this.seen = seen;
			currentlyVisible = visible;
			flagForUpdate();
			return true;
		} else {
			return false;
		}
	}
	
	/**
	 * storing updates is irrelevant to visibility cells, but client classes
	 * won't necessarily know that. Therefore, storeUpdate() is overridden here 
	 * to do nothing.
	 */
	@Override
	public void storeUpdate()
	{
	}
	
	/**
	 * @return the latest update, null if no update needed
	 */
	@Override
	public VisibilityCell grabUpdate()
	{
		if (hasBeenUpdated()) {
			resetUpdate();
			return new VisibilityCell(true, seen, currentlyVisible);
		} else {
			return null;
		}
	}
	
	/**
	 * apply an update to the cell
	 * @param updateCell the cell to update this one with
	 * @throws IllegalArgumentException if updateCell is not a VisibilityCell
	 */
	@Override
	public void applyUpdate(ModelCell updateCell)
		throws IllegalArgumentException
	{
		if (updateCell != null) {
			if (!(updateCell instanceof VisibilityCell)) {
				throw new IllegalArgumentException("Update passed to " + toString() + " was not a VisibilityCell");
			}
		
			VisibilityCell update = (VisibilityCell) updateCell;
			setVisibility(update.hasBeenSeen(), update.isCurrentlyVisible());
		}
	}
}
